﻿using Swsk33.GISEndExercise.Model;
using Swsk33.GISEndExercise.Param;
using Swsk33.GISEndExercise.Util;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Threading;
using System.Windows.Forms;

namespace Swsk33.GISEndExercise
{
	public partial class MainGUI : Form
	{
		/// <summary>
		/// 当前多边形
		/// </summary>
		private Polygon polygon;

		/// <summary>
		/// 绘制器实用类
		/// </summary>
		private ElementPainter painter;

		/// <summary>
		/// 当前选择模式
		/// </summary>
		private SelectMode currentMode = SelectMode.POINT_SELECT;

		/// <summary>
		/// 相交选择时当前点击索引
		/// </summary>
		private int currentPointIndex = 0;

		/// <summary>
		/// 记录当前点击的点
		/// </summary>
		private Point[] clickPoints = new Point[2];

		public MainGUI()
		{
			InitializeComponent();
			painter = new ElementPainter(showArea.CreateGraphics());
		}

		/// <summary>
		/// 读取文件
		/// </summary>
		private void read_Click(object sender, System.EventArgs e)
		{
			// 读取
			string[] texts = File.ReadAllLines(@"..\..\resource\HeNanBoundary.csv");
			result.Text = "读取中...";
			result.ForeColor = Color.Red;
			Application.DoEvents();
			List<PointF> points = new List<PointF>();
			// 从第三行开始
			for (int i = 2; i < texts.Length; i++)
			{
				string[] eachLine = texts[i].Split(',');
				points.Add(new PointF(float.Parse(eachLine[1]), float.Parse(eachLine[2])));
			}
			// 初始化多边形
			polygon = new Polygon(points);
			// 绘制
			showArea.Refresh();
			painter.DrawPolygon(polygon);
			result.Text = "读取完成！当前未压缩，面积：" + polygon.GetArea();
			result.ForeColor = Color.Blue;
		}

		/// <summary>
		/// 压缩线段
		/// </summary>
		private void zip_Click(object sender, System.EventArgs e)
		{
			if (polygon == null)
			{
				return;
			}
			result.Text = "压缩中...";
			result.ForeColor = Color.Red;
			Application.DoEvents();
			// 压缩多边形
			polygon = polygon.Compress();
			// 显示
			showArea.Refresh();
			painter.DrawPolygon(polygon);
			result.Text = "压缩完成！压缩后面积：" + polygon.GetArea();
		}

		/// <summary>
		/// 绘制包络矩形
		/// </summary>
		private void drawEnvelop_Click(object sender, System.EventArgs e)
		{
			if (polygon == null)
			{
				MessageBox.Show("请先读取数据！", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			painter.DrawEnvelope(polygon);
		}

		private void pointSelect_Click(object sender, System.EventArgs e)
		{
			currentMode = SelectMode.POINT_SELECT;
			pointSelect.Enabled = false;
			intersectSelect.Enabled = true;
		}

		private void intersectSelect_Click(object sender, System.EventArgs e)
		{
			currentMode = SelectMode.INTERSECT_SELECT;
			pointSelect.Enabled = true;
			intersectSelect.Enabled = false;
		}

		private void showArea_MouseClick(object sender, MouseEventArgs e)
		{
			if (polygon == null)
			{
				return;
			}
			if (currentMode == SelectMode.POINT_SELECT)
			{
				// 依次计算点击位置到每一个遍历的线段的垂距并判断是否在阈值范围内
				PointF clickPoint = new PointF(e.X, e.Y);
				Line currentToNext;
				for (int i = 0; i < polygon.Points.Length; i++)
				{
					if (i == polygon.Points.Length - 1)
					{
						currentToNext = new Line(polygon.Points[i], polygon.Points[0]);
					}
					else
					{
						currentToNext = new Line(polygon.Points[i], polygon.Points[i + 1]);
					}
					// 先判断角度
					Vector startToPoint = new Vector(currentToNext.Start, clickPoint);
					Vector endToPoint = new Vector(currentToNext.End, clickPoint);
					Vector startToEnd = new Vector(currentToNext);
					Vector endToStart = new Vector(currentToNext.End, currentToNext.Start);
					if (startToPoint.GetAngle(startToEnd) > 90 || endToPoint.GetAngle(endToStart) > 90)
					{
						continue;
					}
					// 再判断垂距
					if (currentToNext.GetPointToLineOffset(clickPoint) < 3)
					{
						painter.DrawPolygonStrong(polygon);
						break;
					}
				}
			}
			else if (currentMode == SelectMode.INTERSECT_SELECT)
			{
				clickPoints[currentPointIndex] = new Point(e.X, e.Y);
				painter.drawPoint(clickPoints[currentPointIndex]);
				currentPointIndex++;
				if (currentPointIndex == 2)
				{
					currentPointIndex = 0;
					Line line = new Line(clickPoints[0], clickPoints[1]);
					painter.drawLine(line);
					// 判断是否相交
					bool flag = false;
					Line currentLine;
					for (int i = 0; i < polygon.Points.Length; i++)
					{
						if (i == polygon.Points.Length - 1)
						{
							currentLine = new Line(polygon.Points[i], polygon.Points[0]);
						}
						else
						{
							currentLine = new Line(polygon.Points[i], polygon.Points[i + 1]);
						}
						if (currentLine.IsIntersect(line))
						{
							flag = true;
							break;
						}
					}
					Thread.Sleep(500);
					showArea.Refresh();
					painter.DrawPolygon(polygon);
					if (flag)
					{
						painter.DrawPolygonStrong(polygon);
					}
				}
			}
		}

		private void clear_Click(object sender, System.EventArgs e)
		{
			if (polygon == null)
			{
				return;
			}
			showArea.Refresh();
			painter.DrawPolygon(polygon);
		}
	}
}